
#ifndef __QE_I2C_H__
#define __QE_I2C_H__



#include "qe_device.h"



#define QE_I2C_WR                0x0000
#define QE_I2C_RD               (1u << 0)
#define QE_I2C_ADDR_10BIT       (1u << 2)  /* this is a ten bit chip address */
#define QE_I2C_NOSTART          (1u << 4)
#define QE_I2C_IGNORE_NACK      (1u << 5)
#define QE_I2C_NO_READ_ACK      (1u << 6)  /* when I2C reading, we do not ACK */
#define QE_I2C_NO_STOP          (1u << 7)

#define QE_I2C_DEV_CTRL_10BIT        0x20
#define QE_I2C_DEV_CTRL_ADDR         0x21
#define QE_I2C_DEV_CTRL_TIMEOUT      0x22
#define QE_I2C_DEV_CTRL_RW           0x23
#define QE_I2C_DEV_CTRL_CLK          0x24

typedef struct {
    qe_u16 addr;
    qe_u16 flags;
    qe_u16 len;
    qe_u8  *buf;
}qe_i2c_message;

struct qe_dev_i2c_bus;
typedef struct qe_dev_i2c_bus qe_i2c_bus;

typedef struct {
    qe_int (*master_xfer)(qe_i2c_bus *bus, qe_i2c_message *msgs, qe_uint num);
    qe_int (*slave_xfer)(qe_i2c_bus *bus, qe_i2c_message *msgs, qe_uint num);
    qe_ret (*ioctl)(qe_i2c_bus *bus, qe_u32, qe_u32);
} qe_i2c_bus_ops;

typedef struct qe_dev_i2c_bus {
    qe_dev parent;
    const qe_i2c_bus_ops *ops;
    qe_u16  flags;
    qe_u16  addr;
    qe_u32  timeout;
    qe_u32  retries;
    
    void *priv;

    qe_lock lock;

	qe_u32 multi_access:1;
	qe_u32 reserve:31;
}qe_i2c_bus;

typedef struct {
    qe_i2c_message *msgs;
    qe_size  number;
}qe_i2c_priv_data;



qe_ret qe_i2c_bus_register(qe_i2c_bus *bus, const char *name, qe_i2c_bus_ops *ops, void *priv);

qe_i2c_bus *qe_i2c_bus_find(const char *name);

qe_int qe_i2c_transfer(qe_i2c_bus *bus, qe_i2c_message *msgs, qe_uint num);

qe_ret qe_i2c_control(qe_i2c_bus *bus, qe_u32 cmd, qe_u32 arg);

qe_int qe_i2c_master_send(qe_i2c_bus *bus, qe_u16 addr,
	qe_u16 flags, const qe_u8 *buf, qe_u32 count);

qe_int qe_i2c_master_recv(qe_i2c_bus *bus, qe_u16 addr,
    qe_u16 flags, qe_u8 *buf, qe_u32 count);

/**
 * @brief I2C bus set lock
 * @param[in] bus: I2C bus
 * @param[in] lock: lock reference
 * @param[in] acquire: lock acquire function
 * @param[in] release: lock release function
 */
qe_ret qe_i2c_bus_setlock(qe_i2c_bus *bus, qe_ptr lock,
	qe_lock_acquire acquire, qe_lock_release release);

/**
 * @brief I2C transfer with lock
 * @param[in] bus: I2C bus
 * @param[in] msgs: transfer messages
 * @param[in] num: transfer messages number
 * @param[in] wait: lock wait timeout
 * @return >0:success <:error
 */
qe_int qe_i2c_transfer_wait(qe_i2c_bus *bus, qe_i2c_message msgs[], 
	qe_u32 num, qe_uint wait);

qe_int qe_i2c_master_recv_wait(qe_i2c_bus *bus, qe_u16 addr,
    qe_u16 flags, qe_u8 *buf, qe_u32 count, qe_uint wait);

qe_int qe_i2c_master_send_wait(qe_i2c_bus *bus, qe_u16 addr,
	qe_u16 flags, const qe_u8 *buf, qe_u32 count, qe_uint wait);



#endif /* __QE_I2C_H__ */

